<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>手写防抖函数</title>
  <style>
    .container {
      width: 100%;
      height: 300px;
      line-height: 300px;
      text-align: center;
      color: #fff;
      background-color: #444;
      font-size: 66px;
    }
  </style>
</head>

<body>
  <div class="container"></div>

  <script>
    let container = document.querySelector('.container');
    let count = 1;
    // 定义 countAdd 为需要被频繁调用的函数，此处用count++代替
    function countAdd(e) {
      console.log(this);
      // 此处this一开始指向window, debounce防抖函数中写入了改变this指向，将this指向于container
      console.log(e);
      // e 一开始为 undefined, 通过arguments拿到
      container.innerHTML = count++;
    }
    container.onmousemove = debounce(countAdd, 300);

    // 防抖:
    // 事件响应函数在一段时间后执行，如果在这段时间内再次调用，则重新计算执行时间；当预定的时间内没有再次调用该函数，则执行countAdd函数。
    // 第一个参数为需要进行防抖操作的函数
    // 第二个参数为延迟时间

    // 初步实现功能版本
    function debounce(func, delay) {
      let timer = null;
      return function () {
        if (timer !== null) clearTimeout(timer);
        timer = setTimeout(func, delay);
      }
    }

    // 改变内部this指向和获得e 版本
    function debounce(func, delay) {
      let timer = null;
      return function () {
        // console.log(this); // 此处this指向container
        let context = this; // 先把this保存起来
        // console.log(arguments); // 获取
        let args = arguments;
        if (timer !== null) clearTimeout(timer);
        timer = setTimeout(function () {
          // 利用apply方法改变this指向
          func.apply(context, args);
        }, delay);
      }
    }


    // 实现步骤：
    // 1. 初步完成防抖函数
    // function debounce(func, delay) {
    //   let timer = null;
    //   return function () {
    //     if (timer !== null) clearTimeout(timer);
    //     timer = setTimeout(func, delay);
    //   }
    // }
    // 2. 改变this指向，让当前的this指向当前的container
    // function debounce(func, delay) {
    //   let timer = null;
    //   return function () {
    //     // console.log(this); // 此处this指向container
    //     let context = this; // 先把this保存起来
    //     if (timer !== null) clearTimeout(timer);
    //     timer = setTimeout(function () {
    //       // 利用apply方法改变this指向
    //       func.apply(context);
    //     }, delay);
    //   }
    // }
    // 3. e 一开始为 undefined，此时则需要拿到 e
    // function debounce(func, delay) {
    //   let timer = null;
    //   return function () {
    //     // console.log(this); // 此处this指向container
    //     let context = this; // 先把this保存起来

    //     // console.log(arguments); // 获取
    //     let args = arguments;

    //     if (timer !== null) clearTimeout(timer);
    //     timer = setTimeout(function () {
    //       // 利用apply方法改变this指向
    //       func.apply(context, args);
    //     }, delay);
    //   }
    // }

  </script>
</body>

</html>